package cn.yj.lock.aqs;

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 永健
 * @since 2022-02-24 12:20
 */
public class AppSync extends AbstractAqs implements Serializable {



    /**
     * 同一个锁资源来抢锁，就使用同一把锁，来一个加1，走一个减1
     */
    private AtomicInteger count = new AtomicInteger(0);

    public int getCount() {
        return count.get();
    }

    public void increment() {
        count.incrementAndGet();
    }

    public int decrementAndGet() {
       return count.decrementAndGet();
    }

    @Override
    protected boolean tryAcquire(int arg) {
        final Thread current = Thread.currentThread();
        System.out.println(current.getName() + " 尝试拿锁...");
        int state = getState();
        // 可获取锁
        if (state == 0) {
            // cas 获取锁
            if (!hasQueuedPredecessors()) {
                super.compareAndSetState(0, arg);
                // 设置持锁的线程
                setExclusiveOwnerThread(current);
                System.out.println(Thread.currentThread().getName() + " 获取锁成功");
                return true;
            }
        }
        return false;
    }


    @Override
    protected boolean tryRelease(int arg) {
        // 释放锁
        int c = getState() - arg;

        // 加锁和持有锁的线程不是同一个
        if (Thread.currentThread() != getExclusiveOwnerThread()) {
            throw new IllegalMonitorStateException();
        }
        boolean free = false;
        if (c == 0) {
            free = true;
            setExclusiveOwnerThread(null);
        }
        setState(c);
        return free;
    }

}
